package com.ari.eft.command;

import java.io.StringWriter;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.ari.eft.request.type.EFTRequest;
import com.ari.eft.request.type.LoginRequest;
import com.ari.xml.XMLResultGenerator;

public class LoginPreviewCommand implements Command, XMLResultGenerator {

    private LoginRequest request;
    private String xml;

    public void execute() {
        try {
            xml = generateXML();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void setRequest(LoginRequest request) {
        this.request = request;
    }

    public LoginRequest getRequest() {
        return request;
    }

    public String getXML() {
        String genXML = null;
        try {
            genXML = generateXML();
        } catch (ParserConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return genXML;
    }

    public void setRequest(EFTRequest incomingReq) {
        if (incomingReq instanceof LoginRequest) {
            request = (LoginRequest) incomingReq;
        } else {
            // throw an exception
        }
    }

    /**
     * @return
     * @throws ParserConfigurationException
     * @throws Exception
     */
    public String generateXML() throws ParserConfigurationException, Exception {
        final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        final DocumentBuilder docBuilder = factory.newDocumentBuilder();
        final Document doc = docBuilder.newDocument();
        final Element epp = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "epp");
        // epp.setAttributeNS("urn:ietf:params:xml:ns:epp-1.0", "xmlns",
        // "urn:ietf:params:xml:ns:epp-1.0");
        epp.setAttribute("xmlns", "urn:ietf:params:xml:ns:epp-1.0");
        epp.setAttribute("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance");
        epp.setAttribute("xsi:schemaLocation", "urn:ietf:params:xml:ns:epp-1.0 epp-1.0.xsd");
        final Element command = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "command");
        final Element login = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "login");
        final Element clientIdentifier = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "clID");
        final Element password = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "pw");
        final Element newPassword = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "newPW");
        doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "objURI");
        final Element svcs = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "svcs");
        final Element svcExt = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "svcExtension");
        final Element extURI = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "extURI");
        final Element options = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "options");
        final Element version = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "version");
        final Element language = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "lang");
        final Element clientTransId = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "clTRID");
        doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "version");
        doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "lang");
        
        epp.appendChild(command);
        command.appendChild(login);

        login.appendChild(clientIdentifier);
        login.appendChild(password);
        login.appendChild(newPassword);
        login.appendChild(options);
        login.appendChild(svcs);
        command.appendChild(clientTransId);
        
        String[] objURIArr = request.getObjURI().split("\r\n");

        for (String eachURI : objURIArr) {
            final Element localObjURI = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "objURI");
            localObjURI.setTextContent(eachURI);
            svcs.appendChild(localObjURI);
        }

        String[] extObjURIArr = request.getExtensions().split("\r\n");

        for (String eachURI : extObjURIArr) {
            final Element localExtObjURI = doc.createElementNS("urn:ietf:params:xml:ns:epp-1.0", "extURI");
            localExtObjURI.setTextContent(eachURI);
            svcExt.appendChild(localExtObjURI);
        }

        // svcExt.appendChild(extURI);
        svcs.appendChild(svcExt);
        options.appendChild(version);
        options.appendChild(language);

        clientIdentifier.setTextContent(request.getClientIdentifier());
        password.setTextContent(request.getPassword());
        newPassword.setTextContent(request.getNewPassword());
        // objURI.setTextContent(request.getObjURI());
        extURI.setTextContent(request.getExtensions());
        clientTransId.setTextContent(request.getClientTransactionId());
        
        version.setTextContent(request.getVersion());
        language.setTextContent(request.getLanguage());

        clientTransId.setTextContent(request.getClientTransactionId());

        // Printing XML
        final TransformerFactory transformerFactory = TransformerFactory.newInstance();
        final Transformer transformer = transformerFactory.newTransformer();
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        final DOMSource source = new DOMSource(epp);
        final StringWriter strWriter = new StringWriter();
        final StreamResult result = new StreamResult(strWriter);
        transformer.transform(source, result);
        return strWriter.toString();
    }

}
